package com.example.demo.excel2csv.service.impl;

import com.example.demo.excel2csv.dto.AnalyzeData;
import com.example.demo.excel2csv.dto.CsvData;
import com.example.demo.excel2csv.service.IExcel2CsvService;
import com.example.demo.utils.CSVUtils;
import com.example.demo.utils.ExcelUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.*;

/**
 * ******************************************************
 *
 * @author liugh9
 * @version 1.0
 * @classname Excel2CsvServiceImpl
 * @description
 * @date 2023/11/22 15:35
 * <p>
 * ******************************************************
 */
@Slf4j
@Service
public class Excel2CsvServiceImpl implements IExcel2CsvService, CommandLineRunner {

    @Value("${csv_path}")
    private String CSV_PATH;

    @Value("${excel_path}")
    private String EXCEL_PATH;

    @Value("${column_size}")
    private int columnSize;


    /**
     * 一个文件的一个sheet页对应一个csv文件，倘若字段超出了200,就分成两个csv文件
     *
     * @param file
     */
    @Override
    public void excel2Csv(MultipartFile file) throws IOException {

        String originalFilename = file.getOriginalFilename();
        String fileNamePart = originalFilename.substring(0, originalFilename.lastIndexOf('.'));


        List<AnalyzeData> analyzeDataResult = new LinkedList<>();
        ExcelUtils.importExcel(file, analyzeDataResult);
//        log.info("excel解析结果：{}", analyzeDataResult);
        for (AnalyzeData analyzeData : analyzeDataResult) {
            List<Map<String, Object>> dataList = analyzeData.getDataList();
            List<String> columns = analyzeData.getColumns();
            String sheetName = analyzeData.getSheetName();

            StringBuilder stringBuilder = new StringBuilder();
            for (String column : columns) {
                stringBuilder.append(column).append(",");
            }
            stringBuilder.deleteCharAt(stringBuilder.length() - 1);
            String sTitle = stringBuilder.toString();
            String fName = CSV_PATH + File.separator + fileNamePart + "-" + sheetName + ".csv";
            File newFile = new File(fName);
            if (!newFile.exists()) {
                newFile.createNewFile();
            }
            String mapKey = stringBuilder.toString();
            try (final OutputStream os = new FileOutputStream(newFile)) {
                CSVUtils.doExport(dataList, sTitle, mapKey, os);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    @Override
    public void excel2Csv() throws IOException {

        File excelDir = new File(EXCEL_PATH);

        File[] files = excelDir.listFiles();

        for (File item : files) {

            String originalFilename = item.getName();
            String fileNamePart = originalFilename.substring(0, originalFilename.lastIndexOf('.'));


            List<AnalyzeData> analyzeDataResult = new LinkedList<>();
            ExcelUtils.importExcel(item, analyzeDataResult);
//            log.info("excel解析结果：{}", analyzeDataResult);
            for (AnalyzeData analyzeData : analyzeDataResult) {
                List<Map<String, Object>> dataList = analyzeData.getDataList();
                List<String> columns = analyzeData.getColumns();
                String sheetName = analyzeData.getSheetName();

                StringBuilder stringBuilder = new StringBuilder();
                for (String column : columns) {
                    stringBuilder.append(column).append(",");
                }
                stringBuilder.deleteCharAt(stringBuilder.length() - 1);
                String sTitle = stringBuilder.toString();
                String fName = CSV_PATH + File.separator + fileNamePart + "-" + sheetName + ".csv";
                File newFile = new File(fName);
                if (!newFile.exists()) {
                    newFile.createNewFile();
                }
                String mapKey = stringBuilder.toString();
                try (final OutputStream os = new FileOutputStream(newFile)) {
                    CSVUtils.doExport(dataList, sTitle, mapKey, os);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    public void transferCsvByDirAndColumn() throws IOException {

        File excelDir = new File(EXCEL_PATH);

        File[] files = excelDir.listFiles();

        for (File item : files) {

            String originalFilename = item.getName();
            String fileNamePart = originalFilename.substring(0, originalFilename.lastIndexOf('.'));


            List<AnalyzeData> analyzeDataResult = new LinkedList<>();
            ExcelUtils.importExcel(item, analyzeDataResult);
//            log.info("excel解析结果：{}", analyzeDataResult);
            for (AnalyzeData analyzeData : analyzeDataResult) {
                List<CsvData> csvDatas = new ArrayList<>();
                splitColumn(analyzeData, csvDatas, fileNamePart);
                for (CsvData csvData : csvDatas) {
                    List<Map<String, Object>> dataList = csvData.getDataList();
                    List<String> columns = csvData.getColumns();
                    String fName = csvData.getFileName();


                    StringBuilder stringBuilder = new StringBuilder();
                    for (String column : columns) {
                        stringBuilder.append(column).append(",");
                    }
                    stringBuilder.deleteCharAt(stringBuilder.length() - 1);
                    String sTitle = stringBuilder.toString();

                    File newFile = new File(fName);
                    if (!newFile.exists()) {
                        newFile.createNewFile();
                    }
                    String mapKey = stringBuilder.toString();
                    try (final OutputStream os = new FileOutputStream(newFile)) {
                        CSVUtils.doExport(dataList, sTitle, mapKey, os);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    private void splitColumn(AnalyzeData analyzeData, List<CsvData> csvDatas, String fileNamePart) {
        String sheetName = analyzeData.getSheetName();
        int currSheetColumn = analyzeData.getCurrSheetColumn();
        if (currSheetColumn <= columnSize) {
            String fName = CSV_PATH + File.separator + fileNamePart + "-" + sheetName + ".csv";
            CsvData csvData = new CsvData();
            csvDatas.add(csvData);
            csvData.setColumns(analyzeData.getColumns());
            csvData.setDataList(analyzeData.getDataList());
            csvData.setFileName(fName);
        } else {
            List<String> analyzeDataColumns = analyzeData.getColumns();
            // 共有i个columnSize - 1大小的数据
            int i = (currSheetColumn + columnSize - 1 - 1) / (columnSize - 1);
            for (int j = 0; j < i; j++) {
                String fName = CSV_PATH + File.separator + fileNamePart + "-" + sheetName + "-" + (j + 1) + ".csv";
                CsvData csvData = new CsvData();
                csvDatas.add(csvData);
                // 前columnSize - 1列
                List<String> columns = new ArrayList<>();
                for (int k = 0; k < columnSize - 1; k++) {
                    int p = j * (columnSize - 1) + k;
                    if (p < currSheetColumn) {
                        columns.add(analyzeDataColumns.get(p));
                    } else {
                        break;
                    }
                }
                csvData.setColumns(columns);
                csvData.setFileName(fName);
                splitDataList(analyzeData.getDataList(), columns, csvData);

            }
        }
    }

    private void splitDataList(List<Map<String, Object>> dataList, List<String> columns, CsvData csvData) {
        List<Map<String, Object>> csvDataList = new ArrayList<>();
        csvData.setDataList(csvDataList);
        for (int i = 0; i < dataList.size(); i++) {
            Map<String, Object> map = dataList.get(i);
            Map<String, Object> csvMap = new HashMap<>();
            csvDataList.add(csvMap);
            for (String column : columns) {
                csvMap.put(column, map.get(column));
            }
            csvMap.put("associationKey", i + 1);
        }
        csvData.getColumns().add("associationKey");

    }


    @Override
    public void run(String... args) throws Exception {
        File file = new File(CSV_PATH);
        if (!file.exists()) {
            file.mkdirs();
        }
    }
}
